package ru.sgu.diploma.practic.service.impl;

import ru.sgu.diploma.practic.domain.model.AutomatResult;
import ru.sgu.diploma.practic.domain.model.Point;
import ru.sgu.diploma.practic.errors.NextLetterException;
import ru.sgu.diploma.practic.service.AutomatResultConverter;
import ru.sgu.diploma.practic.service.AutomatUltraMetricResultConverter;

import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;

/**
 * User: datmakin
 * Date: 15.03.11
 * Email: atmakin.dv@gmail.com
 */
public class AutomatUltraMetricResultsConverterImpl implements AutomatUltraMetricResultConverter {

    private Integer maxn;

    public List<Point> convert(String[] input, String[] output, String[] alphabet) throws NextLetterException {
        List<Point> result = new LinkedList<Point>();

        StringBuffer binaryIn = new StringBuffer();
        String in = "";
        for (int i = 0; i < input.length; i++) {
            binaryIn.append(getNumber(input[i], alphabet));
            in = binaryIn.toString();
        }

        String out = "";
        StringBuffer binaryOut = new StringBuffer();
        for (int i = 0; i < input.length; i++) {
            binaryOut.append(getNumber(output[i], alphabet));
            out = binaryOut.toString();
        }

        for (int i = 0; i < maxn && i < in.length() && i < out.length(); i++) {
            Double x = castStringToNumber(in, i, alphabet.length);
            Double y = castStringToNumber(out, i, alphabet.length);
            result.add(new Point(x, y));
        }
        return result;
    }

    private Double castStringToNumber(String target, Integer i, Integer base) {
        String numStr = (new StringBuffer(target.substring(target.length()-i-1, target.length()))).toString();
        Long num = Long.parseLong(numStr, 2);
        return num / Math.pow(2, i + 1);
    }

    private String getNumber(String letter, String[] alphabet) throws NextLetterException {

        for (int i = 0; i < alphabet.length; i++)
            if (alphabet[i].equals(letter))
                return Integer.toBinaryString(i);

        throw new NextLetterException("letter not found");
    }

    public Integer getMaxn() {
        return maxn;
    }

    public void setMaxn(Integer maxn) {
        this.maxn = maxn;
    }
}
